﻿#include "ipmaskcalculate.h"
#include <chmslog.h>

#include <QString>

/*
 * 对象计数器
 * */
int IPMaskCalculate::sNewCounter = 0;

IPMaskCalculate::IPMaskCalculate()
{

}

// 网络地址
std::array<unsigned int, 4> IPMaskCalculate::funArrayOfIpNetAddr_IPv4(const unsigned int &prefix, const std::array<unsigned int, 4> &ip_inaddr) const
{
    // 函数返回值
    std::array< unsigned int, 4 > varUIntNetAddr = {0,0,0,0};

    std::array<unsigned int, 4> varUIntNetAddrTmp = { 0,0,0,0 };

    varUIntNetAddrTmp = kaMapPrefixMask_IPv4.find(prefix)->second;

    varUIntNetAddr[0] = ip_inaddr[0] & varUIntNetAddrTmp[0];
    varUIntNetAddr[1] = ip_inaddr[1] & varUIntNetAddrTmp[1];
    varUIntNetAddr[2] = ip_inaddr[2] & varUIntNetAddrTmp[2];
    varUIntNetAddr[3] = ip_inaddr[3] & varUIntNetAddrTmp[3];

    return varUIntNetAddr;
}

// 广播地址
std::array<unsigned int, 4> IPMaskCalculate::funArrayOfBroadcastAddr_IPv4(const unsigned int &prefix, const std::array<unsigned int, 4> &ip_inaddr) const
{

    // 广播地址，函数返回值
    std::array<unsigned int, 4> varUIntBroadcastAddr = {0,0,0,0};

    std::array< unsigned int, 4 > varUIntNetAddr = { 0,0,0,0 };  // 网络地址
    std::array<unsigned int, 4> varUIntNetAddrTmp = { 0,0,0,0 };  // 临时变量

    varUIntNetAddrTmp = kaMapPrefixMask_IPv4.find(prefix)->second;  // 获得网络地址

    varUIntNetAddr[0] = ip_inaddr[0] & varUIntNetAddrTmp[0];
    varUIntNetAddr[1] = ip_inaddr[1] & varUIntNetAddrTmp[1];
    varUIntNetAddr[2] = ip_inaddr[2] & varUIntNetAddrTmp[2];
    varUIntNetAddr[3] = ip_inaddr[3] & varUIntNetAddrTmp[3];

    varUIntBroadcastAddr[0] = varUIntNetAddr[0];
    varUIntBroadcastAddr[1] = varUIntNetAddr[1];
    varUIntBroadcastAddr[2] = varUIntNetAddr[2];
    varUIntBroadcastAddr[3] = varUIntNetAddr[3];

    switch(prefix)
    {
    case 32:
        do {
            return ip_inaddr;
        } while (false);
        break;

    case 31:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 1;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 30:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 3;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 29:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 7;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 28:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 15;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 27:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 31;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 26:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 63;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 25:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 127;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 24:
        do {
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 23:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 1;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 22:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 3;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 21:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 7;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 20:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 15;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 19:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 31;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 18:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 63;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 17:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 127;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 16:
        do {
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 15:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 1;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 14:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 3;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 13:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 7;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 12:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 15;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 11:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 31;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 10:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 63;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 9:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 127;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 8:
        do {
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 7:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 1;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 6:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 3;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 5:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 7;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 4:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 15;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 3:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 31;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 2:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 63;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    case 1:
        do {
            varUIntBroadcastAddr[0] = varUIntNetAddr[0] + 127;
            varUIntBroadcastAddr[1] = varUIntNetAddr[1] + 255;
            varUIntBroadcastAddr[2] = varUIntNetAddr[2] + 255;
            varUIntBroadcastAddr[3] = varUIntNetAddr[3] + 255;
            return varUIntBroadcastAddr;
        } while (false);
        break;

    default:
        break;
    }

    return varUIntBroadcastAddr;
}

// 起始IP地址
std::array<unsigned int, 4> IPMaskCalculate::funArrayOfFirstAddr_IPv4(const unsigned int &prefix, const std::array<unsigned int, 4> &ip_inaddr) const
{
    // 函数返回值
    std::array<unsigned int,4> varArrFirstAddr = {0,0,0,0};

    // 临时变量
    std::array<unsigned int,4> varArrFirstAddrTmp = {0,0,0,0};

    varArrFirstAddr = ip_inaddr;
    varArrFirstAddrTmp = IPMaskCalculate::funArrayOfIpNetAddr_IPv4(prefix,ip_inaddr);

    switch(prefix)
    {
    case 32:
        do{
            return varArrFirstAddr;
        }while(false);
        break;

    default:
        do{
            varArrFirstAddr = varArrFirstAddrTmp;
            varArrFirstAddr[3] = varArrFirstAddrTmp[3] + 1;
            return varArrFirstAddr;
        }while(false);
        break;
    }

    return varArrFirstAddr;
}

// 结束IP地址
std::array<unsigned int, 4> IPMaskCalculate::funArrayOfLastAddr_IPv4(const unsigned int &prefix, const std::array<unsigned int, 4> &ip_inaddr) const
{
    // 函数返回值
    std::array<unsigned int, 4> varArrLastAddr = {0,0,0,0};

    varArrLastAddr = IPMaskCalculate::funArrayOfBroadcastAddr_IPv4(prefix,ip_inaddr);

    switch(prefix)
    {
    case 32:
        do{
            //
            return ip_inaddr;
        }while(false);
        break;

    case 31:
        do{
            //
            return ip_inaddr;
        }while(false);
        break;
    default:
        do{
            //

            varArrLastAddr[3]--;

            return varArrLastAddr;
        }while(false);
        break;
    }
    return varArrLastAddr;
}


/*
 * 对象计数器 取数
 * */
int IPMaskCalculate::sFunGetCounter()
{
    return sNewCounter;
}

/*
 * 重载 new
 * */
void *IPMaskCalculate::operator new(size_t s)
{
    ++sNewCounter;
    // 程序刚启动时加载配置文件之前是不显示的，因为debug开关标识还未被读取
    std::string str1 = "new of IPMaskCalculate : ";
    ChMSLog::funVoidViewCounter(str1,sNewCounter);
    return ::operator new(s);
}

/*
 * 重载 new
 * */
void *IPMaskCalculate::operator new(size_t s,void * p)
{
    ++sNewCounter;
    // 程序刚启动时加载配置文件之前是不显示的，因为debug开关标识还未被读取
    std::string str1 = "new of IPMaskCalculate : ";
    ChMSLog::funVoidViewCounter(str1,sNewCounter);
    return ::operator new(s,p);
}

/*
 * 重载 delete
 * */
void IPMaskCalculate::operator delete(void *ptr)
{
    --sNewCounter;
    std::string str1 = "delete of IPMaskCalculate : ";
    ChMSLog::funVoidViewCounter(str1,sNewCounter);
    return ::operator delete(ptr);
}
